home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / c / shell.c < prev    next >
C/C++ Source or Header  |  1996-09-13  |  7KB  |  365 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: shell.c,v 1.6 1996/09/13 17:52:11 digulla Exp $
  4.     $Log: shell.c,v $
  5.     Revision 1.6  1996/09/13 17:52:11  digulla
  6.     Use IPTR
  7.  
  8.     Revision 1.5  1996/09/12 14:47:55  digulla
  9.     More stack
  10.  
  11.     Revision 1.4  1996/08/30 17:02:03  digulla
  12.     Fixed a bug which caused the shell to exit if the timer sent a signal. This
  13.     fix is a very bad hack :(
  14.  
  15.     Revision 1.3  1996/08/23 17:05:58  digulla
  16.     Increased the stack.
  17.  
  18.     Revision 1.2  1996/08/01 17:40:46  digulla
  19.     Added standard header for all files
  20.  
  21.     Desc:
  22.     Lang:
  23. */
  24. #include <exec/memory.h>
  25. #include <exec/libraries.h>
  26. #include <clib/exec_protos.h>
  27. #include <dos/dosextens.h>
  28. #include <dos/rdargs.h>
  29. #include <clib/dos_protos.h>
  30. #include <utility/tagitem.h>
  31.  
  32. CALLENTRY /* Before the first symbol */
  33.  
  34. struct ExecBase *SysBase;
  35. struct DosLibrary *DOSBase;
  36.  
  37. static void tinymain(void);
  38.  
  39. LONG entry(struct ExecBase *sysbase)
  40. {
  41.     SysBase=sysbase;
  42.     DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39);
  43.     if(DOSBase!=NULL)
  44.     {
  45.     if(Input())
  46.         tinymain();
  47.     CloseLibrary((struct Library *)DOSBase);
  48.     }
  49.     return 0;
  50. }
  51.  
  52. static void printpath(void)
  53. {
  54.     BPTR dir;
  55.     STRPTR buf;
  56.     ULONG i;
  57.     dir=CurrentDir(0);
  58.     for(i=256;;i+=256)
  59.     {
  60.     buf=AllocVec(i,MEMF_ANY);
  61.     if(buf==NULL)
  62.         break;
  63.     if(NameFromLock(dir,buf,i))
  64.     {
  65.         FPuts(Output(),buf);
  66.         FreeVec(buf);
  67.         break;
  68.     }
  69.     FreeVec(buf);
  70.     }
  71.     CurrentDir(dir);
  72. }
  73.  
  74. static void prompt(void)
  75. {
  76.     printpath();
  77.     FPuts(Output(),"> ");
  78.     Flush(Output());
  79. }
  80.  
  81. struct linebuf
  82. {
  83.     BPTR file;
  84.     UBYTE *buf;
  85.     ULONG size;
  86.     ULONG bend;
  87.     ULONG lend;
  88.     LONG eof;
  89. };
  90.  
  91. static LONG readline(struct linebuf *lb)
  92. {
  93.     if(lb->bend)
  94.     {
  95.     UBYTE *src=lb->buf+lb->lend, *dst=lb->buf;
  96.     ULONG i=lb->bend-lb->lend;
  97.     if(i)
  98.         do
  99.         *dst++=*src++;
  100.         while(--i);
  101.     lb->bend-=lb->lend;
  102.     }
  103.     lb->lend=0;
  104.     for(;;)
  105.     {
  106.     LONG subsize;
  107.     for(;lb->lend<lb->bend;)
  108.         if(lb->buf[lb->lend++]=='\n')
  109.         {
  110.         lb->buf[lb->lend-1]='\0';
  111.         return 0;
  112.         }
  113.     if(lb->eof)
  114.     {
  115.         FreeVec(lb->buf);
  116.         lb->buf=NULL;
  117.         lb->eof=0;
  118.         return 0;
  119.     }
  120.     if(lb->bend>=lb->size)
  121.     {
  122.         UBYTE *newbuf;
  123.         newbuf=AllocVec(lb->size+256,MEMF_ANY);
  124.         if(newbuf==NULL)
  125.         {
  126.         FreeVec(lb->buf);
  127.         lb->buf=NULL;
  128.         return ERROR_NO_FREE_STORE;
  129.         }
  130.         CopyMem(lb->buf,newbuf,lb->bend);
  131.         FreeVec(lb->buf);
  132.         lb->buf=newbuf;
  133.         lb->size+=256;
  134.     }
  135.     subsize=Read(lb->file,lb->buf+lb->bend,lb->size-lb->bend);
  136.     if(subsize==0)
  137.     {
  138.         if(lb->bend)
  139.         lb->buf[lb->bend++]='\n';
  140.         lb->eof=1;
  141.     }else if(subsize<0)
  142.     {
  143.         /*ada 30.8.96 This is a REALLY BAD hack !! */
  144.         if (IoErr() != -1)
  145.         {
  146.         VPrintf("Got Error\n", NULL);
  147.         FreeVec(lb->buf);
  148.         lb->buf=NULL;
  149.         return IoErr();
  150.         }
  151.     }else
  152.         lb->bend+=subsize;
  153.     }
  154. }
  155.  
  156. BPTR loadseg(STRPTR name)
  157. {
  158.     BPTR old, *cur, seg;
  159.     STRPTR s;
  160.     seg=LoadSeg(name);
  161.     if(seg)
  162.     return seg;
  163.     s=name;
  164.     while(*s)
  165.     {
  166.     if(*s==':'||*s=='/')
  167.         return 0;
  168.     s++;
  169.     }
  170.     old=CurrentDir(0);
  171.     cur=(BPTR *)BADDR(Cli()->cli_CommandDir);
  172.     while(cur!=NULL)
  173.     {
  174.     (void)CurrentDir(cur[1]);
  175.     seg=LoadSeg(name);
  176.     if(seg)
  177.         break;
  178.     cur=(BPTR *)BADDR(cur[0]);
  179.     }
  180.     CurrentDir(old);
  181.     return seg;
  182. }
  183.  
  184. LONG execute(STRPTR com)
  185. {
  186.     STRPTR s1=NULL, s2=NULL;
  187.     STRPTR args, rest, command=NULL, infile=NULL, outfile=NULL;
  188.     STRPTR last;
  189.     BPTR in=0, out=0;
  190.     BPTR seglist, lock;
  191.     struct FileInfoBlock *fib;
  192.     LONG res, size, error=0;
  193.     struct CSource cs;
  194.  
  195.     last=com;
  196.     while(*last++)
  197.     ;
  198.     args=s1=(STRPTR)AllocVec(last-com+1,MEMF_ANY);
  199.     rest=s2=(STRPTR)AllocVec(last-com+1,MEMF_ANY);
  200.     if(args==NULL||rest==NULL)
  201.     {
  202.     error=ERROR_NO_FREE_STORE;
  203.     goto end;
  204.     }
  205.  
  206.     cs.CS_Buffer=com;
  207.     cs.CS_Length=last-com-1;
  208.     cs.CS_CurChr=0;
  209.  
  210.     for(;;)
  211.     {
  212.     while(com[cs.CS_CurChr]==' '||com[cs.CS_CurChr]=='\t')
  213.         *rest++=com[cs.CS_CurChr++];
  214.     if(com[cs.CS_CurChr]==';')
  215.         break;
  216.     if(command==NULL)
  217.         command=args;
  218.     else if(com[cs.CS_CurChr]=='<')
  219.         infile=args+1;
  220.     else if(com[cs.CS_CurChr]=='>')
  221.         outfile=args+1;
  222.     else
  223.     {
  224.         size=cs.CS_CurChr;
  225.         res=ReadItem(args,~0ul/2,&cs);
  226.         while(size<cs.CS_CurChr)
  227.         *rest++=com[size++];
  228.         if(res==ITEM_NOTHING||res==ITEM_ERROR)
  229.         {
  230.         *rest++=0;
  231.         break;
  232.         }
  233.         continue;
  234.     }
  235.     res=ReadItem(args,~0ul/2,&cs);
  236.     if(res!=ITEM_QUOTED&&res!=ITEM_UNQUOTED)
  237.         break;
  238.     while(*args++)
  239.         ;
  240.     }
  241.     if(command==NULL||!*command)
  242.     goto end;
  243.     if(infile!=NULL)
  244.     {
  245.     in=Open(infile,MODE_OLDFILE);
  246.     if(!in)
  247.     {
  248.         infile=NULL;
  249.         error=IoErr();
  250.         goto end;
  251.     }
  252.     in=SelectInput(in);
  253.     }
  254.     if(outfile!=NULL)
  255.     {
  256.     out=Open(outfile,MODE_NEWFILE);
  257.     if(!out)
  258.     {
  259.         outfile=NULL;
  260.         error=IoErr();
  261.         goto end;
  262.     }
  263.     out=SelectOutput(out);
  264.     }
  265.     seglist=loadseg(command);
  266.     if(seglist)
  267.     {
  268.     last=s2;
  269.     while(*last++)
  270.         ;
  271.     RunCommand(seglist,100000,s2,last-s2-1);
  272.     UnLoadSeg(seglist);
  273.     }else if(infile==NULL&&outfile==NULL)
  274.     {
  275.     lock=Lock(command,SHARED_LOCK);
  276.     if(lock)
  277.     {
  278.         fib=AllocDosObject(DOS_FIB,NULL);
  279.         if(fib!=NULL)
  280.         {
  281.         if(Examine(lock,fib))
  282.         {
  283.             if(fib->fib_DirEntryType>0)
  284.             lock=CurrentDir(lock);
  285.             else
  286.             SetIoErr(error=ERROR_OBJECT_WRONG_TYPE);
  287.         }
  288.         FreeDosObject(DOS_FIB,fib);
  289.         }
  290.         UnLock(lock);
  291.     }
  292.     else
  293.         error = IoErr ();
  294.     }
  295.  
  296. end:
  297.     if(infile!=NULL)
  298.     Close(SelectInput(in));
  299.     if(outfile!=NULL)
  300.     Close(SelectOutput(out));
  301.     FreeVec(s1);
  302.     FreeVec(s2);
  303.     if(error)
  304.     PrintFault(error,"Couldn't run command");
  305.     Flush(Output());
  306.     return 0;
  307. }
  308.  
  309. int executefile(STRPTR name)
  310. {
  311.     struct linebuf lb = { 0, NULL, 0, 0, 0, 0 };
  312.     LONG error=0;
  313.  
  314.     lb.file=Open(name,MODE_OLDFILE);
  315.     if(lb.file)
  316.     {
  317.     for(;;)
  318.     {
  319.         error=readline(&lb);
  320.         if(error||lb.buf==NULL)
  321.         break;
  322.         error = execute(lb.buf);
  323.         if (error != 0)
  324.         PrintFault (error, "execute:");
  325.     }
  326.     Close(lb.file);
  327.     }else
  328.     error=IoErr();
  329.     return error;
  330. }
  331.  
  332. static void tinymain(void)
  333. {
  334.     struct RDArgs *rda;
  335.     STRPTR args[2]={ "S:Shell-Startup", NULL };
  336.     struct linebuf lb = { 0, NULL, 0, 0, 0, 0 };
  337.     LONG error=0;
  338.  
  339.     lb.file=Input();
  340.     rda=ReadArgs("FROM,COMMAND/K/F",(IPTR *)args,NULL);
  341.     if(rda!=NULL)
  342.     {
  343.     if(args[1])
  344.         execute((STRPTR)args[1]);
  345.     else
  346.     {
  347.         ULONG num=((struct Process *)FindTask(NULL))->pr_TaskNum;
  348.         VPrintf("New Shell process %ld\n",&num);
  349.         Flush(Output());
  350.         executefile((STRPTR)args[0]);
  351.         for(;;)
  352.         {
  353.         prompt();
  354.         error=readline(&lb);
  355.         if(error||lb.buf==NULL)
  356.             break;
  357.         execute(lb.buf);
  358.         }
  359.         VPrintf("Process %ld ending\n",&num);
  360.         Flush(Output());
  361.     }
  362.     FreeArgs(rda);
  363.     }
  364. }
  365.